package com.zhongan.gateway.filter;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.zhongan.gateway.bean.Api;
import com.zhongan.gateway.common.enums.GatewayErrorCodeEnum;
import com.zhongan.gateway.common.exception.GatewayException;
import com.zhongan.gateway.dto.ResponseBase;
import com.zhongan.gateway.service.RedisService;

/**
 * api调用次数记录
 */
@Component
public class ApiErrorZuulFilter extends ZuulFilter {

    private Logger       logger = LoggerFactory.getLogger(ApiErrorZuulFilter.class);

    @Resource
    private RedisService redisService;

    @Override
    public String filterType() {
        return "error";
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    @Override
    public boolean shouldFilter() {

        return true;
    }

    @Override
    public Object run() {
        logger.info("封装异常信息开始...");

        HttpServletRequest request = RequestContext.getCurrentContext().getRequest();

        ResponseBase rb = (ResponseBase) request.getAttribute("responseBase");
        GatewayException ge = (GatewayException) request.getAttribute("gatewayException");
        //没有返回值
        if (null == rb) {
            rb = new ResponseBase();
            Long t = System.currentTimeMillis();
            rb.setTimestamp(t.toString());
            if (null != ge) {
                //校验未通过异常
                rb.setCode(ge.getErrorCode());
                rb.setMessage(ge.getMessage());
            } else {
                //未知异常
                Throwable ta = RequestContext.getCurrentContext().getThrowable();
                logger.error("捕获未知异常：" + ta.getMessage(), ta);
                rb.setCode(GatewayErrorCodeEnum.UN_KNOWN.getCode());
                rb.setMessage(GatewayErrorCodeEnum.UN_KNOWN.getMsg());
                request.setAttribute("gatewayException", new GatewayException(GatewayErrorCodeEnum.UN_KNOWN.getCode(),
                        GatewayErrorCodeEnum.UN_KNOWN.getMsg()));
                //触发熔断机制
                fuse(request);
            }
        } else {
            Throwable ta = RequestContext.getCurrentContext().getThrowable();
            logger.error("api返回值不为空却抛出异常..." + ta.getMessage(), ta);
        }
        request.setAttribute("responseBase", rb);
        logger.info("封装异常信息结束...");
        return null;
    }

    //触发熔断机制
    private void fuse(HttpServletRequest request) {
        Api api = (Api) request.getAttribute("api");
        if (null != api) {
            String key = api.getServiceName() + "_" + api.getVersion();

            int i = redisService.fuse(key);
            logger.info("api fusing ...key={},count={}", key, i);
        }

    }

}
